<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if(!function_exists('folder_copy'))
{
	function folder_copy($src, $dest, $path = '', $force = false, $use_streams = false)
	{
		@set_time_limit(ini_get('max_execution_time'));

		if ($path)
		{
			$src = path_clean($path . '/' . $src);
			$dest = path_clean($path . '/' . $dest);
		}

		// Eliminate trailing directory separators, if any
		$src = rtrim($src, DIRECTORY_SEPARATOR);
		$dest = rtrim($dest, DIRECTORY_SEPARATOR);

		if (!folder_exists($src))
		{
			throw new RuntimeException('Source folder not found', -1);
		}
		if (folder_exists($dest) && !$force)
		{
			throw new RuntimeException('Destination folder already exists', -1);
		}

		// Make sure the destination exists
		if (!folder_create($dest))
		{
			throw new RuntimeException('Cannot create destination folder', -1);
		}

		// If we're using ftp and don't have streams enabled
		if(false)
		{
		}
		else
		{
			if (!($dh = @opendir($src)))
			{
				throw new RuntimeException('Cannot open source folder', -1);
			}
			// Walk through the directory copying files and recursing into folders.
			while (($file = readdir($dh)) !== false)
			{
				$sfid = $src . '/' . $file;
				$dfid = $dest . '/' . $file;

				switch (filetype($sfid))
				{
					case 'dir':
						if ($file != '.' && $file != '..')
						{
							$ret = folder_copy($sfid, $dfid, null, $force, $use_streams);

							if ($ret !== true)
							{
								return $ret;
							}
						}
						break;

					case 'file':
						if ($use_streams)
						{
						}
						else
						{
							if (!@copy($sfid, $dfid))
							{
								throw new RuntimeException('Copy file failed', -1);
							}
						}
						break;
				}
			}
		}
		return true;
	}
}

if(!function_exists('folder_create'))
{
	function folder_create($path = '', $mode = 0755)
	{
		static $nested = 0;

		// Check to make sure the path valid and clean
		$path = path_clean($path);

		// Check if parent dir exists
		$parent = dirname($path);

		if (!folder_exists($parent))
		{
			// Prevent infinite loops!
			$nested++;

			if (($nested > 20) || ($parent == $path))
			{
				$nested--;

				return false;
			}

			// Create the parent directory
			if (folder_create($parent, $mode) !== true)
			{
				// Folder::create throws an error
				$nested--;

				return false;
			}

			// OK, parent directory has been created
			$nested--;
		}

		// Check if dir already exists
		if (folder_exists($path))
		{
			return true;
		}

		// Check for safe mode
		if (false)
		{
		}
		else
		{
			// We need to get and explode the open_basedir paths
			$obd = ini_get('open_basedir');

			// If open_basedir is set we need to get the open_basedir that the path is in
			if ($obd != null)
			{
				if (IS_WIN)
				{
					$obdSeparator = ";";
				}
				else
				{
					$obdSeparator = ":";
				}

				// Create the array of open_basedir paths
				$obdArray = explode($obdSeparator, $obd);
				$inBaseDir = false;

				// Iterate through open_basedir paths looking for a match
				foreach ($obdArray as $test)
				{
					$test = path_clean($test);

					if (strpos($path, $test) === 0)
					{
						$inBaseDir = true;
						break;
					}
				}
				if ($inBaseDir == false)
				{

					return false;
				}
			}

			// First set umask
			$origmask = @umask(0);

			// Create the path
			if (!$ret = @mkdir($path, $mode))
			{
				@umask($origmask);

				return false;
			}

			// Reset umask
			@umask($origmask);
		}
		return $ret;
	}
}

if(!function_exists('folder_delete'))
{
	function folder_delete($path)
	{
		@set_time_limit(ini_get('max_execution_time'));

		// Sanity check
		if (!$path)
		{
			return false;
		}

		try
		{
			// Check to make sure the path valid and clean
			$path = path_clean($path);
		}
		catch (UnexpectedValueException $e)
		{
			throw $e;
		}

		// Is this really a folder?
		if (!is_dir($path))
		{
			return false;
		}

		// Remove all the files in folder if they exist; disable all filtering
		$files = folder_files($path, '.', false, true, array(), array());

		if (!empty($files))
		{
			require_once(dirname(__FILE__). DIRECTORY_SEPARATOR .'file.php');

			if (file_delete($files) !== true)
			{
				// file_delete throws an error
				return false;
			}
		}

		// Remove sub-folders of folder; disable all filtering
		$folders = folder_folders($path, '.', false, true, array(), array());

		foreach ($folders as $folder)
		{
			if (is_link($folder))
			{
				if (file_delete($folder) !== true)
				{
					// file_delete throws an error
					return false;
				}
			}
			elseif (folder_delete($folder) !== true)
			{
				// Folder::delete throws an error
				return false;
			}
		}


		if (false)
		{
		}

		// In case of restricted permissions we zap it one way or the other
		// as long as the owner is either the webserver or the ftp.
		if (@rmdir($path))
		{
			return true;
		}

		return false;
	}
}

if(!function_exists('folder_exists'))
{
	function folder_exists($path)
	{
		return is_dir(path_clean($path));
	}
}

if(!function_exists('folder_files'))
{
	function folder_files($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
		$excludefilter = array('^\..*', '.*~'), $naturalSort = false)
	{
		// Check to make sure the path valid and clean
		$path = path_clean($path);

		// Is the path a folder?
		if (!is_dir($path))
		{
			return false;
		}

		// Compute the excludefilter string
		if (count($excludefilter))
		{
			$excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
		}
		else
		{
			$excludefilter_string = '';
		}

		// Get the files
		$arr = _folder_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true);

		// Sort the files based on either natural or alpha method
		if ($naturalSort)
		{
			natsort($arr);
		}
		else
		{
			asort($arr);
		}

		return array_values($arr);
	}
}

if(!function_exists('folder_folders'))
{
	function folder_folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
		$excludefilter = array('^\..*'))
	{
		// Check to make sure the path valid and clean
		$path = path_clean($path);

		// Is the path a folder?
		if (!is_dir($path))
		{

			return false;
		}

		// Compute the excludefilter string
		if (count($excludefilter))
		{
			$excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
		}
		else
		{
			$excludefilter_string = '';
		}

		// Get the folders
		$arr = _folder_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false);

		// Sort the folders
		asort($arr);

		return array_values($arr);
	}
}

if(!function_exists('_folder_items'))
{
	function _folder_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles)
	{
		@set_time_limit(ini_get('max_execution_time'));

		$arr = array();

		// Read the source directory
		if (!($handle = @opendir($path)))
		{
			return $arr;
		}

		while (($file = readdir($handle)) !== false)
		{
			if ($file != '.' && $file != '..' && !in_array($file, $exclude)
				&& (empty($excludefilter_string) || !preg_match($excludefilter_string, $file)))
			{
				// Compute the fullpath
				$fullpath = $path . '/' . $file;

				// Compute the isDir flag
				$isDir = is_dir($fullpath);

				if (($isDir xor $findfiles) && preg_match("/$filter/", $file))
				{
					// (fullpath is dir and folders are searched or fullpath is not dir and files are searched) and file matches the filter
					if ($full)
					{
						// Full path is requested
						$arr[] = $fullpath;
					}
					else
					{
						// Filename is requested
						$arr[] = $file;
					}
				}

				if ($isDir && $recurse)
				{
					// Search recursively
					if (is_int($recurse))
					{
						// Until depth 0 is reached
						$arr = array_merge($arr, _folder_items($fullpath, $filter, $recurse - 1, $full, $exclude, $excludefilter_string, $findfiles));
					}
					else
					{
						$arr = array_merge($arr, _folder_items($fullpath, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles));
					}
				}
			}
		}

		closedir($handle);

		return $arr;
	}
}

if(!function_exists('folder_listFolderTree'))
{
	function folder_listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0)
	{
		$dirs = array();

		if ($level == 0)
		{
			$GLOBALS['_Folder_folder_tree_index'] = 0;
		}

		if ($level < $maxLevel)
		{
			$folders = folder_folders($path, $filter);

			// First path, index foldernames
			foreach ($folders as $name)
			{
				$id = ++$GLOBALS['_Folder_folder_tree_index'];
				$fullName = path_clean($path . '/' . $name);
				$dirs[] = array('id' => $id, 'parent' => $parent, 'name' => $name, 'fullname' => $fullName,
					'relname' => str_replace(JPATH_ROOT, '', $fullName));
				$dirs2 = folder_listFolderTree($fullName, $filter, $maxLevel, $level + 1, $id);
				$dirs = array_merge($dirs, $dirs2);
			}
		}

		return $dirs;
	}
}

if(!function_exists('folder_makeSafe'))
{
	function folder_makeSafe($path)
	{
		$regex = array('#[^A-Za-z0-9_\\\/\(\)\[\]\{\}\#\$\^\+\.\'~`!@&=;,-]#');

		return preg_replace($regex, '', $path);
	}
}
